import Axios from 'axios'
import { HttpConfig, HttpRequestConfig, HttpResponse } from './types'
import { HttpError, wrapAxios } from './utils'

export * from './types'

export const create = <CT extends HttpRequestConfig = HttpRequestConfig>(
  config: HttpConfig,
  before: (config: CT) => PromiseValue<CT>,
  after: (req: CT, e?: any, resp?: HttpResponse<any, CT>) => PromiseValue<any>
) => {
  const axios = Axios.create({ ...config, validateStatus: () => true })
  axios.interceptors.request.use((config) => {
    return before(config as unknown as CT) as any
  })
  axios.interceptors.response.use(
    (resp) => {
      return after(
        resp.config as unknown as CT,
        undefined,
        resp as unknown as HttpResponse<any, CT>
      )
    },
    (e) => {
      if (!e.config) throw e
      const httpError = HttpError.from(e, e?.message, Axios.isCancel(e))
      return after(e.config, httpError, e.response)
    }
  )
  return wrapAxios<any, CT>(axios)
}
